﻿using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Transactions;
using System.Xml;

namespace Microsoft.Biztalk.Adapters.Wcf.NullBinding
{
    class NullChannelBase : ChannelBase
    {
        internal CommittableTransaction InternalTransaction { get; set; }
        protected NullBindingProperties Properties { get; set; }

        public NullChannelBase(ChannelManagerBase channelManager, NullBindingProperties props)
            : base(channelManager)
        {
            this.Properties = props;
        }

        protected override void OnAbort()
        {
        }

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override void OnClose(TimeSpan timeout)
        {
        }

        protected override void OnEndClose(IAsyncResult result)
        {
        }

        protected override void OnEndOpen(IAsyncResult result)
        {
        }

        protected override void OnOpen(TimeSpan timeout)
        {
        }

        protected TimeSpan EvaluateTimeOut(TimeSpan timeout)
        {
            if (this.Properties.MessagesPerSecond <= 0 || this.Properties.MessagesPerSecond > 1000)
            {
                return TimeSpan.MinValue;
            }
            int milliSecondsPerMessage = (int)(1000 / this.Properties.MessagesPerSecond);
            TimeSpan messageTimeSpan = new TimeSpan(0, 0, 0, 0, milliSecondsPerMessage);

            if (timeout > messageTimeSpan)
            {
                return messageTimeSpan;
            }
            else
                return timeout;
        }

        protected CommittableTransaction GetMessageAndTransaction(out Message message, bool isTwoWay)
        {
            message = null;
            if (this.State == CommunicationState.Closed)
                return null;
            message = Message.CreateMessage(MessageVersion.Default, Helpers.Action,(object)this.Properties.MessageBody);
            message.Headers.To = new Uri(Helpers.Address);

            if (this.Properties.IsQueued)
                Helpers.LogCreatedMessage(message, this.Properties.LogMessages, MessageType.Input);
            else
                Helpers.LogCreatedMessage(message, this.Properties.LogMessages, MessageType.Request);

            if (this.Properties.IsTransacted && !this.Properties.IsQueued)
            {
                this.InternalTransaction = new CommittableTransaction();
                Transaction.Current = this.InternalTransaction;
            }
            return this.InternalTransaction;
        }
    }
}
